package yxy.banana.server.internal;

import java.io.IOException;

import com.google.protobuf.InvalidProtocolBufferException;

import yxy.apple.logger.Logger;
import yxy.banana.socket.controlled.ChannelManager;
import yxy.banana.socket.controller.client.ClientRegistryController;

public abstract class InternalClientController<H extends InternalClientHandler> extends ClientRegistryController<H> {

	private static final Logger logger = Logger.create(InternalClientController.class);
	private static final ChannelManager<? extends InternalClientHandler> manager = new ChannelManager<>();

	@Override
	protected void opened() {
		logger.debug("连接开启\r\n%s", this.toString());
	}

	@Override
	protected void closed() {
		logger.debug("连接关闭\r\n%s", this.toString());
	}

	@Override
	protected void actived() {
		logger.info("连接可用aaaa\r\n%s", this.toString());
		// 启动心跳
		this.pace(this.getHeartbeatInterval(), this.getHeartbeatResponseTimeout());
		// 发起注册
		try {
			this.register(this.getRegistryResponseTimeout());
		} catch (Exception e) {
			logger.warn("向路由中心发起注册时出现异常，连接将被断开...\r\n%s", this.toString());
			this.caught(e);
			this.handler().disconnect();
		}
	}

	@Override
	protected void inactived() {
		logger.warn("连接失活\r\n%s", this.toString());
		// 停止心跳
		this.arrest();
		// 从可用簇通道中移除，但此时尚未未注销
		this.bundler().remove(this.handler());
	}

	@Override
	protected void triggered(Object event) {
		logger.warn("发生预期外的事件(%s)触发，请检查代码！\r\n%s", event, this.toString());
	}

	@Override
	protected void thrown(Throwable cause) {
		if (cause instanceof InvalidProtocolBufferException) {
			logger.error("捕获到InvalidProtocolBufferException异常，请检查代码！\r\n%s", this.toString());
			logger.error(cause);
		} else if (cause instanceof IOException) {
			// IO异常只计入trace
			logger.trace(cause);
		} else {
			// logger.warn("捕获到异常，请联系开发人员评估。\r\n%s", this.toString());
			logger.warn(cause);
		}
	}

	@Override
	protected void dropped(Object message, DroppedReason reason) {
		logger.warn("有消息存在问题被丢弃，请检查代码！\r\n原因：%s\r\n%s\r\n", reason.name(), message, this.toString());
	}

	@Override
	protected void registered(boolean result) {
		if (result) {
			// 加入可用通道簇
			this.bundler().add(this.handler());
			logger.info("内部通道注册成功!\r\n%s", this.toString());
		} else {
			logger.error("内部通道注册失败，请检查代码或配置！\r\n%s", this.toString());
		}
	}

	@Override
	protected void announced(long delta) {
		logger.debug("收到心跳回应，延迟%d毫秒\r\n%s", delta, this.toString());
	}

	@Override
	protected void silenced(int times) {
		logger.warn("第%d次出现心跳静默，请检查内部网络！\r\n%s", times, this.toString());
	}

	protected abstract int getHeartbeatInterval();

	protected abstract int getHeartbeatResponseTimeout();

	protected abstract int getRegistryResponseTimeout();

	protected abstract InternalClientBundler<H> bundler();

	@SuppressWarnings("unchecked")
	@Override
	protected ChannelManager<H> manager() {
		return (ChannelManager<H>) manager;
	}
}
